package com.xcity.game.buff;

import java.util.Objects;

import com.alibaba.fastjson.annotation.JSONField;
import com.xcity.db.entity.Player;

import naga.x.App;
import naga.x.common.Updatable;
import naga.x.game.template.TemplateService;
import naga.x.game.time.TimeUpdater;

public class Buff implements Updatable {

	public static final String FIELD_ID = "1";
	public static final String FIELD_CREATE_TIME = "2";
	public static final String FIELD_USED_TIMES = "3";
	public static final String FIELD_DURATION = "4";
	
	@JSONField(name = FIELD_ID)
	protected int id;
	@JSONField(name = FIELD_CREATE_TIME)
	protected long createTime;
	@JSONField(name = FIELD_USED_TIMES)
	protected int usedTimes;
	@JSONField(name = FIELD_DURATION)
	protected int duration; // 持续时间(秒)，为0则从template里取
	
	@JSONField(serialize = false, deserialize = false)
	protected BuffTemplate template;
	
	public Buff() {}
	
	public Buff(int id, BuffTemplate template) {
		this(id, TimeUpdater.getInstance().now(), 0, template);
	}
	
	public Buff(int id, long createTime, int usedTimes, BuffTemplate template) {
		this(id, createTime, usedTimes, 0, template);
	}
	
	public Buff(int id, long createTime, int usedTimes, int duration, BuffTemplate template) {
		this.id = id;
		this.createTime = createTime;
		this.usedTimes = usedTimes;
		this.duration = duration;
		this.template = Objects.requireNonNull(template);
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
		this.template = App.getApp().getServiceManager().get(TemplateService.class).get(BuffTemplate.class, id);
	}

	public long getCreateTime() {
		return createTime;
	}

	public void setCreateTime(long createTime) {
		this.createTime = createTime;
	}

	public int getUsedTimes() {
		return usedTimes;
	}

	public void setUsedTimes(int usedTimes) {
		this.usedTimes = usedTimes;
	}

	public BuffTemplate getTemplate() {
		return template;
	}

	public void setTemplate(BuffTemplate template) {
		this.template = template;
	}
	
	public void addUsedTimes(int n) {
		usedTimes += n;
	}
	
	public boolean effect(Player player) {
		BuffEffector eff = BuffEffectFactory.create(this);
		return eff != null && eff.effect(this, player);
	}
	
	public boolean uneffect(Player player) {
		BuffEffector eff = BuffEffectFactory.create(this);
		return eff != null && eff.uneffect(this, player);
	}
	
	@JSONField(serialize = false)
	public int getLeftCD() {
		int cd = getDuration();
		if (cd == -1) {
			return Integer.MAX_VALUE;
		}
		int left = (int) (cd * 1000 + createTime - TimeUpdater.getInstance().now());
		return left > 0 ? left : 0;
	}
	
	@JSONField(serialize = false)
	public long getEndTime() {
		return getDuration() * 1000 + createTime;
	}

	@Override
	public boolean update() {
		int du = getDuration();
		if (du == -1) { // 永久有效
			return false;
		}
		// 失效返回true
		return createTime + du * 1000 <= TimeUpdater.getInstance().now();
	}
	
	public int getDuration() {
		return duration != 0 ? duration : getTemplate().getDuration();
	}
	
	public void setDuration(int duration) {
		this.duration = duration;
	}
	
}
